package com.meilingcloud.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.meilingcloud.common.constant.Constants;
import com.meilingcloud.common.enums.LabelTempStatus;
import com.meilingcloud.system.domain.SysLabelTemp;
import com.meilingcloud.system.domain.SysLabelType;
import com.meilingcloud.system.mapper.SysLabelTempMapper;
import com.meilingcloud.system.service.ISysLabelTempService;
import com.meilingcloud.system.service.ISysLabelTypeService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 标签模板 Service业务层处理
 *
 * @author chenl
 * @date 2021-04-14
 */
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Service
public class SysLabelTempServiceImpl extends ServiceImpl<SysLabelTempMapper, SysLabelTemp> implements ISysLabelTempService {

    private final ISysLabelTypeService sysLabelTypeService;

    @Override
    public List<SysLabelTemp> queryList(SysLabelTemp sysLabelTemp) {
        LambdaQueryWrapper<SysLabelTemp> lqw = Wrappers.lambdaQuery();
        if (sysLabelTemp.getLabelTypeId() != null) {
            lqw.eq(SysLabelTemp::getLabelTypeId, sysLabelTemp.getLabelTypeId());
        }
        if (StringUtils.isNotBlank(sysLabelTemp.getLabelTempName())) {
            lqw.like(SysLabelTemp::getLabelTempName, sysLabelTemp.getLabelTempName());
        }
        return this.list(lqw);
    }

    @Override
    public List<SysLabelTemp> handleResult(List<SysLabelTemp> sysLabelTemps) {
        List<Long> labelTypeIds = sysLabelTemps.stream().map(SysLabelTemp::getLabelTypeId).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(labelTypeIds)) {
            List<SysLabelType> sysLabelTypes = sysLabelTypeService.listByIds(labelTypeIds);
            List<SysLabelTemp> collect = sysLabelTemps.stream().map(item ->
                    sysLabelTypes.stream().filter(t -> ObjectUtil.equal(item.getLabelTypeId(), t.getLabelTypeId()))
                            .map(t -> {
                                item.setLabelTypeCode(t.getLabelTypeCode());
                                item.setLabelTypeName(t.getLabelTypeName());
                                item.setLabelWidth(t.getLabelWidth());
                                item.setLabelHeight(t.getLabelHeight());
                                item.setLabelPageWidth(t.getLabelPageWidth());
                                item.setLabelPageHeight(t.getLabelPageHeight());
                                return item;
                            }).findAny().get()
            ).collect(Collectors.toList());
            return collect;
        }
        return sysLabelTemps;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveTemp(SysLabelTemp sysLabelTemp) {
        return this.save(handleTempActive(sysLabelTemp));
    }

    @CacheEvict(value = Constants.LABEL_TEMP_KEY, allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateTemp(SysLabelTemp sysLabelTemp) {
        return this.updateById(handleTempActive(sysLabelTemp));
    }

    @Cacheable(value = Constants.LABEL_TEMP_KEY, unless = "#result == null ", cacheManager = "cacheManager1d")
    @Override
    public SysLabelTemp getActiveTemp() {
        SysLabelTemp sysLabelTemp = this.getOne(new LambdaQueryWrapper<SysLabelTemp>()
                .eq(SysLabelTemp::getActive, LabelTempStatus.ACTIVE.getCode()).last("limit 1"));
        if (ObjectUtil.isNotEmpty(sysLabelTemp) && ObjectUtil.isNotEmpty(sysLabelTemp.getLabelTypeId())) {
            SysLabelType sysLabelType = sysLabelTypeService.getById(sysLabelTemp.getLabelTypeId());
            if (ObjectUtil.isNotEmpty(sysLabelType)) {
                BeanUtil.copyProperties(sysLabelType, sysLabelTemp);
            }
        }
        return sysLabelTemp;
    }

    @CacheEvict(value = Constants.LABEL_TEMP_KEY, allEntries = true)
    @Override
    public boolean removeTemps(List<Long> labelTempIds) {
        return this.removeByIds(labelTempIds);
    }

    @Transactional(rollbackFor = Exception.class)
    public SysLabelTemp handleTempActive(SysLabelTemp sysLabelTemp) {
        if (StringUtils.isBlank(sysLabelTemp.getActive())) {
            return sysLabelTemp;
        }
        if (sysLabelTemp.getActive().equals(LabelTempStatus.INACTIVE.getCode())) {
            // 若没有默认启用，则启用
            int count = this.count(new LambdaQueryWrapper<SysLabelTemp>().eq(SysLabelTemp::getActive, LabelTempStatus.ACTIVE.getCode()));
            if (count == 0) {
                sysLabelTemp.setActive(LabelTempStatus.ACTIVE.getCode());
            }
        } else {
            // 若新增为启用状态，则将其他启用状态更改为不启用
            List<SysLabelTemp> sysLabelTemps = this.list(new LambdaQueryWrapper<SysLabelTemp>()
                    .eq(SysLabelTemp::getActive, LabelTempStatus.ACTIVE.getCode()));
            if (CollectionUtil.isNotEmpty(sysLabelTemps)) {
                List<SysLabelTemp> collect = sysLabelTemps.stream()
                        .map(item -> item.setActive(LabelTempStatus.INACTIVE.getCode())).collect(Collectors.toList());
                this.updateBatchById(collect);
            }
        }
        return sysLabelTemp;
    }

    @Cacheable(value = Constants.LABEL_TEMP_KEY, key = "#labelTempId", unless = "#result == null ", cacheManager = "cacheManager1d")
    @Override
    public SysLabelTemp getTempById(Long labelTempId) {
        SysLabelTemp sysLabelTemp = this.getById(labelTempId);
        if (ObjectUtil.isNotEmpty(sysLabelTemp.getLabelTypeId())) {
            SysLabelType sysLabelType = sysLabelTypeService.getById(sysLabelTemp.getLabelTypeId());
            if (ObjectUtil.isNotEmpty(sysLabelType)) {
                BeanUtil.copyProperties(sysLabelType, sysLabelTemp);
            }
        }
        return sysLabelTemp;
    }

}
